<template>
  <div :class="`${pre}`">
    <div :class="`${pre}-head`">
      <!-- 左边年减(累减1/累减10) -->
      <a
        :class="`${pre}-prev-decade-btn`"
        v-show="showYears"
        @click="year -= 10"
      >
        «
      </a>
      <a :class="`${pre}-prev-year-btn`" v-show="!showYears" @click="year--">
        «
      </a>
      <!-- 年份范围 -->
      <a
        :class="`${pre}-year-select`"
        v-show="showYears"
        @click="
          showYears = !showYears;
          showMonths = true;
        "
      >
        {{ ys + "-" + ye }}
      </a>
      <!-- 整年 -->
      <template v-if="local.yearSuffix">
        <a
          :class="`${pre}-year-select`"
          @click="
            showYears = !showYears;
            showMonths = false;
          "
          v-show="!showYears"
        >
          {{ year }}{{ local.yearSuffix }}
        </a>
      </template>
      <template v-else>
        <a
          :class="`${pre}-year-select`"
          @click="
            showYears = !showYears;
            showMonths = false;
          "
          v-show="!showYears"
        >
          {{ year }}
        </a>
      </template>
      <!-- 右边年加(累加1/累加10) -->
      <a :class="`${pre}-next-year-btn`" v-show="!showYears" @click="year++">
        »
      </a>
      <a
        :class="`${pre}-next-decade-btn`"
        v-show="showYears"
        @click="year += 10"
      >
        »
      </a>
    </div>
    <div :class="`${pre}-body`">
      <!-- 年 -->
      <div :class="`${pre}-year`" v-show="showYears">
        <a
          v-for="(year, yearIndex) in years"
          @click="clickYear($event, year)"
          :class="[
            yearIndex === 0 || yearIndex === 11 ? `${pre}-date-out` : '',
            renderStyle(year, month, 'YYYY'),
          ]"
          :key="yearIndex"
        >
          {{ year }}
        </a>
      </div>
      <!-- 月 -->
      <div :class="`${pre}-months`" v-show="showMonths">
        <a
          v-for="(month, monthIndex) in local.months"
          @click="clickMonth($event, monthIndex)"
          :class="[renderStyle(year, monthIndex, 'YYYYMM')]"
          :key="monthIndex"
        >
          {{ month }}
        </a>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "month-panel",
  props: {
    value: {
      type: Array,
      default: [],
    },
    multiple: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    const date = this.getDate(this.value);
    return {
      pre: "calendar",
      showYears: false,
      showMonths: true,
      showHours: false,
      showMinutes: false,
      showSeconds: false,
      year: date.year,
      month: date.month,
    };
  },
  watch: {
    value(val) {
      const time = this.getDate(val);
      this.year = time.year;
      this.month = time.month;
    },
  },
  computed: {
    local() {
      return this.$parent.local;
    },
    ys() {
      return parseInt(this.year / 10) * 10;
    },
    ye() {
      return this.ys + 10;
    },
    years() {
      const arr = [];
      let startYear = this.ys - 1;
      while (arr.length < 12) {
        arr.push(startYear++);
      }
      return arr;
    },
  },
  methods: {
    clickYear(e, year) {
      if (e.target.className.indexOf(`${this.pre}-date-disabled`) === -1) {
        this.year = year;
        this.showYears = false;
        this.showMonths = true;
      }
    },
    clickMonth(e, monthsIndex) {
      if (e.target.className.indexOf(`${this.pre}-date-disabled`) === -1) {
        this.month = monthsIndex;
        const currSelectVal = [...this.value];
        const selectMonthDate = this.getYearAndMonth(this.year, monthsIndex);
        if (this.hasMonth(monthsIndex)) {
          currSelectVal.remove(selectMonthDate);
        } else {
          currSelectVal.push(selectMonthDate);
        }
        this.$emit("input", currSelectVal);
        this.$parent.onChange();
      }
    },
    hasMonth(monthsIndex) {
      if (this.value && Array.isArray(this.value) && this.value.length > 0) {
        const has = this.value.find(
          (item) => item === this.getYearAndMonth(this.year, monthsIndex)
        );
        if (has) {
          return true;
        }
      }
      return false;
    },
    getYearAndMonth(year, monthsIndex) {
      let month = Number.parseInt(monthsIndex) + 1;
      if (month <= 9) {
        month = "0" + month;
      }
      return year + "-" + month;
    },
    getDate(val) {
      let date;
      if (this.multiple && Array.isArray(val)) {
        if (val.length > 0) {
          const vals = [...val];
          vals.sort();
          date = new Date(vals[0]);
        } else {
          date = new Date();
        }
      } else {
        date = new Date(val);
      }
      let year = this.year;
      if (!this.year) {
        year = date.getFullYear();
      }
      return {
        year: year,
        month: date.getMonth(),
      };
    },
    renderStyle(year, month, format) {
      const classObj = {};
      let flag = false;
      if (format === "YYYY") {
        flag = year === this.year;
      } else if (format === "YYYYMM") {
        if (this.hasMonth(month)) {
          flag = true;
        }
      }
      classObj[`${this.pre}-date`] = true;
      classObj[`${this.pre}-date-selected`] = flag;
      if (!flag) {
        if (this.isCurrMonth(year, month)) {
          classObj[`${this.pre}-date-curr-month`] = true;
        }
      }
      return classObj;
    },
    isCurrMonth(year, month) {
      const date = new Date();
      const currYearAndMonth = this.getYearAndMonth(
        date.getFullYear(),
        date.getMonth()
      );
      return currYearAndMonth === this.getYearAndMonth(year, month);
    },
  },
};
</script>

<style>
.calendar {
  height: 100%;
  display: flex;
  flex-flow: column nowrap;
}
.calendar + .calendar {
  border-left: solid 1px #eaeaea;
  margin-left: 5px;
  padding-left: 5px;
}
.calendar-head {
  display: flex;
  flex-flow: row nowrap;
  justify-content: center;
  align-items: center;
}

.calendar-head a {
  color: #666;
  font-weight: bold;
  cursor: pointer;
  display: inline-block;
  text-align: center;
  position: absolute;
  padding: 0 5px;
  font-size: 16px;
}

.calendar-head a:hover {
  color: #1284e7;
}

.calendar-head .calendar-year-select,
.calendar-head .calendar-month-select {
  font-size: 14px;
  padding: 0 2px;
  position: relative;
}

.calendar-prev-decade-btn,
.calendar-prev-year-btn {
  left: 6px;
}

.calendar-prev-month-btn {
  left: 24px;
}

.calendar-next-decade-btn,
.calendar-next-year-btn {
  right: 6px;
}

.calendar-next-month-btn {
  right: 24px;
}

.calendar-body {
  width: 196px;
}

.calendar-date {
  font-weight: normal;
  width: 45px;
  height: 45px;
  text-align: center;
  box-sizing: border-box;
  overflow: hidden;
  float: left;
}

.calendar-date:before {
  content: "";
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}

.calendar-date {
  cursor: pointer;
  border-radius: 5px;
  margin: 2px;
}

.calendar-date-out {
  color: #ccc;
}

.calendar-date:hover,
.calendar-date-on {
  background: #eaf8fe;
}

.calendar-date-selected,
.calendar-date-selected:hover {
  color: #fff;
  font-weight: bold;
  background: #1284e7;
}
.calendar-date-curr-month,
.calendar-date-curr-month:hover {
  font-weight: bold;
  color: #1284e7;
}

.calendar-date-disabled {
  cursor: not-allowed !important;
  color: #bcbcbc !important;
  background: #f3f3f3 !important;
}

.calendar-months {
  width: 100%;
  height: 100%;
  background: #fff;
}

.calendar-months a {
  width: 45px;
  height: 45px;
}
</style>
﻿
